特定の時間帯にCPU使用率が高騰した時のみEC2インスタンスを自動で再起動させる方法
困っていた内容
特定の時間帯にCPU使用率が高騰した時のみEC2インスタンスを自動で再起動させたいです。
どうすればいいの?
他にも方法はあると思いますが、今回はEC2内部でcronを使用し、特定の時間にCloudWatchアラームの作成と削除するようにスケジュールを設定しました。
設定方法
EC2インスタンス用のIAMロールを作成する
CloudWatchにアクセス可能なIAMポリシーを設定します。 今回は、IAM ポリシー「CloudWatchFullAccess」をアタッチしました。必要な権限を付与してください。
EC2 を起動する
EC2を起動します。 今回は Amazon Linux 2 を使用しています。
$ cat /etc/os-release NAME="Amazon Linux" VERSION="2" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2" PRETTY_NAME="Amazon Linux 2" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" HOME_URL="https://amazonlinux.com/"
EC2にSSH接続し、Cronを設定する
EC2にSSH接続します。
$ ssh -i "***.pem" ec2-user@ec2-3-96-168-65.ca-central-1.compute.amazonaws.com
CloudWatchアラームを作成するCLI用のJSONファイルを作成します。
$ vi /home/ec2-user/create-cw-alarm-ec2-reboot.json
create-cw-alarm-ec2-reboot.json は以下の内容で設定します。
{ "Namespace": "AWS/EC2", "MetricName": "CPUUtilization", "Dimensions": [ { "Name": "InstanceId", "Value": "i-0cef0c5afe9414797" } ], "AlarmActions": [ "arn:aws:automate:ca-central-1:ec2:reboot" ], "ComparisonOperator": "GreaterThanThreshold", "DatapointsToAlarm": 1, "EvaluationPeriods": 1, "Period": 300, "Statistic": "Maximum", "Threshold": 80, "AlarmDescription": "CPU Utilization with 80% as threshold", "AlarmName": "CPU80-ec2-reboot" }
crontabに下記のように設定します。今回は試しに、5:30pm(UTC) に put-metric-alarm を実行、6:30pm(UTC) delete-alarms を実行するように設定しています。
$ sudo crontab -e 30 17 * * * aws cloudwatch put-metric-alarm --region ca-central-1 --cli-input-json file:///home/ec2-user/create-cw-alarm-ec2-reboot.json 30 18 * * * aws cloudwatch delete-alarms --region ca-central-1 --alarm-names CPU80-ec2-reboot
試してみた
設定した時間に put-metric-alarm が実行されたことを確認しました。
$ sudo tail -f /var/log/cron 〜・〜・〜・〜・ Dec 2 17:30:01 ip-172-31-13-2 CROND[3621]: (root) CMD (aws cloudwatch put-metric-alarm --region ca-central-1 --cli-input-json file:///home/ec2-user/create-cw-alarm-ec2-reboot.json)
CloudWatchコンソールでCloudWatchアラームが作成されていることを確認しました。
一時的にCPUに負荷をかけるため、EC2にStressツールをインストールします。
$ sudo amazon-linux-extras install epel -y $ sudo yum install stress -y $ stress --version stress 1.0.4
StressツールでCPUに負荷をかけます。
$ stress -c 1 stress: info: [3308] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
topコマンドでCPU使用率を確認するため、別ターミナルで同じインスタンスにログインします。 Stressコマンドで100%近くCPUが使用されていることを確認しました。
top - 17:43:18 up 45 min, 3 users, load average: 1.79, 0.70, 0.26 Tasks: 109 total, 3 running, 64 sleeping, 0 stopped, 0 zombie %Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 988916 total, 384800 free, 88380 used, 515736 buff/cache KiB Swap: 0 total, 0 free, 0 used. 761120 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3649 ec2-user 20 0 7584 100 0 R 98.0 0.0 2:36.78 stress 〜・〜・〜・〜・
CloudWatchアラームの状態がアラーム状態となり、設定したアクションにてEC2の再起動が始まったのでターミナルがクローズされました。
Connection to ec2-3-96-168-65.ca-central-1.compute.amazonaws.com closed by remote host. Connection to ec2-3-96-168-65.ca-central-1.compute.amazonaws.com closed.
CloudWatchアラームのコンソールを確認します。CloudWatchメトリクス 「CPUUtilization」が80%を超え、「アラーム状態」となりました。
CloudWatchアラームのアクションが実行されたことを確認しました。
EC2に再度ログインし、OSが再起動されたことを確認しました。
$ last reboot reboot system boot 5.10.147-133.644 Fri Dec 2 17:47 - 17:50 (00:02) reboot system boot 5.10.147-133.644 Fri Dec 2 16:57 - 17:50 (00:53)
再度、CloudWatchアラームのコンソールを確認します。インスタンスが再起動され、CPU使用率が下がったことでアラームの状態が[OK]に変化しました。
設定した時間に delete-alarms が実行されたことを確認しました。
$ sudo tail -f /var/log/cron 〜・〜・〜・〜・ Dec 2 17:30:01 ip-172-31-13-2 CROND[3621]: (root) CMD (aws cloudwatch put-metric-alarm --region ca-central-1 --cli-input-json file:///home/ec2-user/create-cw-alarm-ec2-reboot.json) 〜・〜・〜・〜・ Dec 2 18:30:01 ip-172-31-13-2 CROND[3427]: (root) CMD (aws cloudwatch delete-alarms --region ca-central-1 --alarm-names CPU80-ec2-reboot)